home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #49 (Oct 89) / DMP Source / src / pdef4.c < prev    next >
Text File  |  1989-01-02  |  14KB  |  504 lines

  1. /*
  2.  * Code to implement Printing Dialogs.  Described in rather complete
  3.  * fashion in Technical Note #95.
  4.  */
  5. /*
  6.  * This file is part of the DMP-110 printer driver for the Macintosh
  7.  * series of computers.
  8.  */
  9. /*
  10.  * Earle R. Horton.
  11.  * Wednesday, November 30, 1988
  12.  * All rights reserved.
  13.  */
  14. #include <Windows.h>
  15. #include <Events.h>
  16. #include <Dialogs.h>
  17. #include <Controls.h>
  18. #include <Lists.h>
  19. #include <Fonts.h>
  20. #include <Memory.h>
  21. #include <Resources.h>
  22. #include <ToolUtils.h>
  23. #include <Packages.h>
  24. #include <Menus.h>
  25. #include "dmp-110.h"
  26. #include "compat.h"
  27. /*
  28.  * The Pascal Interface to MPW C 2.0.2 does not fully include the List Manager.
  29.  */
  30. #ifdef macintosh
  31. pascal void LGetCell(Ptr,short *,Cell,ListHandle);
  32. pascal void LSetCell(Ptr,short,Cell,ListHandle);
  33. pascal void LSetSelect(Boolean,Cell,ListHandle);
  34. #endif
  35.  
  36. #ifndef iDevDaisy
  37. #define bDevDaisy   2
  38. #define iDevDaisy   (bDevDaisy << 8)
  39. #endif
  40. #define STYLEDIALOG (0xE000)
  41. #define JOBDIALOG   (0xE001)
  42. #define XTRA        24  /* Six extra longs for our use. */
  43. #define NORMALPRINT 0
  44. #define DLGSIZE     ((long)(sizeof(TPrDlg) + XTRA))
  45. #define extra(tp,i) (* ((long *)((char *)(tp) + sizeof(TPrDlg)) + (i)))
  46. #define TPSIZE      ((long)(sizeof(TPrint)))
  47. /* Items we handle in the job and style dialogs. */
  48. #define CANCELITEM  2
  49. #define STYLETITLE  4
  50. #define STYLELIST    5
  51.  
  52. #define ALLBUTTON   5
  53. #define RANGEBUTTON 6
  54. #define FROMNUM     7
  55. #define TONUM       9
  56. #define COPIES      11
  57. #define FANBUTTON   13
  58. #define SHEETBUTTON 14
  59.  
  60. #ifdef MPU68000     /* Aztec does not yet do prototypes. */
  61. pascal void CallItemProc();
  62. pascal  TPPrDlg CallDlgInit();
  63. #else
  64. pascal void CallItemProc(tp,itemhit,RealAddr)   /* Glue. */
  65. TPPrDlg     tp;
  66. short       itemhit;
  67. ProcPtr     RealAddr;
  68. extern;
  69. pascal  TPPrDlg CallDlgInit(hPrint,RealAddr)    /* Glue. */
  70. THPrint     hPrint;
  71. ProcPtr     RealAddr;
  72. extern;
  73. #endif
  74.  
  75. /*
  76.  * Validate/update a print record.
  77.  */
  78. pascal Boolean  MyPrValidate(hPrint)
  79. THPrint hPrint;
  80. {
  81. THPrint thedefault;
  82.     if(Valid(hPrint)) return FALSE;
  83.     else{
  84.         thedefault = (THPrint)(GetResource('PREC',NORMALPRINT));
  85.         LoadResource(thedefault);
  86.         **hPrint = **thedefault;
  87.         return TRUE;
  88.     }
  89. }
  90.  
  91. /*
  92.  * Printing dialog supervisor function.
  93.  * Reference: Macintosh Technical Note
  94.  * 95.
  95.  */
  96. pascal Boolean  MyPrDlgMain(hPrint,pDlgInit)
  97. THPrint hPrint;
  98. ProcPtr pDlgInit;
  99. {
  100. TPPrDlg tp;
  101. WindowPtr tempport;
  102. short   donetype,itemhit;
  103. Handle  doneitem;
  104. Rect    donebox;
  105. ProcPtr itemproc;
  106.     tp = CallDlgInit(hPrint,pDlgInit);
  107.     itemproc = tp->pItemProc;
  108.     tp->fDone = FALSE;
  109.     tp->fDoIt = FALSE;
  110.     GetPort(&tempport);
  111.     SetPort(tp);
  112.     ShowWindow(tp);
  113.     GetDItem(tp,DONEITEM,&donetype,&doneitem,&donebox);
  114.     PenSize(3,3);
  115.     InsetRect(&donebox,-4,-4);
  116.     FrameRoundRect(&donebox,16,16);
  117.     PenSize(1,1);
  118.     while(!(tp->fDone)){
  119.         ModalDialog(tp->pFltrProc,&itemhit);
  120.         CallItemProc(tp,itemhit,itemproc);
  121.     }
  122.     SetPort(tempport);
  123.     CloseDialog(tp);
  124.     DisposPtr(tp);
  125.     if(tp->fDoIt) (void)MyPrValidate(hPrint);
  126.     return(tp->fDoIt);
  127. }
  128. /*
  129.  * Default item filter for print dialogs.
  130.  */
  131. pascal Boolean  MyFilter(tp,theEvent,itemhit)
  132. TPPrDlg tp;
  133. EventRecord *theEvent;
  134. short       *itemhit;
  135. {
  136. char c;
  137.     if(theEvent->what == keyDown){
  138.         c = (theEvent->message & charCodeMask);
  139.         if( (c == 13) || (c == 3)){ /* Return or Enter. */
  140.             *itemhit = 1;
  141.             return TRUE;
  142.         }
  143.     }
  144.     return  FALSE;
  145. }
  146. /*
  147.  * Style Dialog Filter.  Give it to the List Manager if it is
  148.  * in the list of 'PREC's.  Signal done if a double-click in a
  149.  * cell.  Otherwise, handle via the normal filter.
  150.  */
  151. pascal Boolean  MyStlFilter(tp,theEvent,itemhit)
  152. TPPrDlg tp;
  153. EventRecord *theEvent;
  154. short       *itemhit;
  155. {
  156.     if(*itemhit == STYLELIST){
  157.         GlobalToLocal(&theEvent->where);
  158.         (void)LClick(theEvent->where,theEvent->modifiers,(ListHandle)extra(tp,0));
  159.         LocalToGlobal(&theEvent->where);
  160.         return FALSE;
  161.     }else{
  162.         return MyFilter(tp,theEvent,itemhit);
  163.     }
  164. }
  165. /*
  166.  * This function fills a print record with defaults.  The default values
  167.  * are stored in the Printer resource file, in PREC 0.  This is easy.
  168.  */
  169. pascal void MyPrintDefault(hPrint)
  170. THPrint hPrint;
  171. {
  172. THPrint thedefault;
  173.     thedefault = (THPrint)(GetResource('PREC',NORMALPRINT));
  174.     LoadResource(thedefault);
  175.     **hPrint = **thedefault;    /* What the hey. */
  176. }
  177. /*
  178.  * The next routine handles the style dialog.  Two possibilities exist.
  179.  * If the cancel button is hit, then we signal quit.  The print record
  180.  * is not changed.
  181.  * If the "OK" button is hit, then we have to fill in the new style in the
  182.  * user print record.
  183.  */
  184. pascal void HandleStyleItems(tp,itemhit)
  185. TPPrDlg tp;
  186. short   itemhit;
  187. {
  188.  
  189. short   thenum,type;
  190. Handle  item;
  191. Rect    box,bigbox;
  192. MenuHandle PRECMenu;
  193. long restype;
  194. short resid;
  195. short nitems,i;
  196. THPrint rPrint;
  197. char thestring[256];
  198. Point theCell;
  199.  
  200.     switch(itemhit){
  201.         case DONEITEM:
  202.             SetPt(&theCell,0,0);
  203.             LGetSelect(0xFFFF,&theCell,(ListHandle)extra(tp,0));
  204.             i = 255;
  205.             LGetCell(&thestring[1],&i,theCell,(ListHandle)extra(tp,0));
  206.             thestring[0] = i;
  207.             rPrint = (THPrint)GetNamedResource('PREC',thestring);
  208.             if(rPrint == nil){
  209.                 rPrint = (THPrint)GetResource('PREC',0);
  210.             }
  211.             LoadResource(rPrint);
  212.             (*(tp->hPrintUsr))->prInfo = (*rPrint)->prInfo;
  213.             (*(tp->hPrintUsr))->prInfoPT = (*rPrint)->prInfoPT;
  214.             (*(tp->hPrintUsr))->rPaper = (*rPrint)->rPaper;
  215.             (*(tp->hPrintUsr))->prStl = (*rPrint)->prStl;
  216.             (*(tp->hPrintUsr))->prXInfo = (*rPrint)->prXInfo;
  217.             (*(tp->hPrintUsr))->printX[0] = (*rPrint)->printX[0];
  218.             LDispose((ListHandle)extra(tp,0));
  219.             tp->fDone = TRUE;
  220.             tp->fDoIt = TRUE;
  221.             break;
  222.         case CANCELITEM:
  223.             LDispose((ListHandle)extra(tp,0));
  224.             tp->fDone = TRUE;
  225.             tp->fDoIt = FALSE;
  226.             break;
  227.         default:
  228.             break;
  229.     }
  230. }
  231. /*
  232.  *   Symbolic constants used to make LNew() more readable.
  233.  */
  234. #define       Drawn        0xFFFF
  235. #define       noGrow       0x0000
  236. #define       noHScroll    0x0000
  237. #define       vScroll      0xFFFF
  238. #include <strings.h>
  239. /*
  240.  * User item for putting up a list of available Print Records.
  241.  */
  242. pascal void PRECuserItem(tp,theitem)
  243. TPPrDlg tp;
  244. short theitem;
  245. {
  246. short type,i,j,nitems,id;
  247. Handle item;
  248. Rect listbox,dataBounds;
  249. Point cellSize,theCell;
  250. char thestring[256];
  251. THPrint rPrint;
  252. long restype;
  253. ListHandle   PRECList;
  254. /*
  255.  * First time called, create the list.
  256.  */
  257.     if(extra(tp,0) == nil){
  258.         GetDItem(tp,theitem,&type,&item,&listbox);
  259.         listbox.right -=15;
  260.         SetRect(&dataBounds,0,0,1,0);
  261.         SetPt(&cellSize,0,0);
  262.         PRECList = LNew(&listbox,&dataBounds,cellSize,0,(WindowPtr)tp,
  263.             Drawn,noGrow,noHScroll,vScroll);
  264.         (*PRECList)->selFlags = lDoHAutoscroll + lOnlyOne;
  265.         extra(tp,0) = (long)PRECList;
  266. /*
  267.  * Read in the resources, put the names in the list.
  268.  */
  269.         nitems = CountResources('PREC');
  270.         (void)LAddRow(nitems,0,PRECList);
  271.         for(i=0,j=0;i++<nitems;){
  272.             rPrint = (THPrint)GetIndResource('PREC',i);
  273.             GetResInfo(rPrint,&id,&restype,thestring);
  274.             SetPt(&theCell,0,j++);
  275.             LSetCell(&thestring[1],(short)thestring[0],theCell,PRECList);
  276.             if(((*tp->hPrintUsr))->printX[0] == id){
  277.                 LSetSelect(0xFFFF,theCell,PRECList);
  278.                 LAutoScroll(PRECList);
  279.             }
  280.         }
  281.     }
  282. /*
  283.  * After the first time, just frame the item's Rect, and call LUpdate()
  284.  * to draw the list.
  285.  */
  286.     GetDItem(tp,theitem,&type,&item,&listbox);
  287.     InsetRect(&listbox,-1,-1);
  288.     FrameRect(&listbox);
  289.     LUpdate(tp->Dlg.window.port.visRgn,(ListHandle)extra(tp,0));
  290. }
  291. /*
  292.  * The style dialog initializer.  Get the dialog from the resource
  293.  * file, calculate the Rect for the Print Record list.
  294.  */
  295. pascal  TPPrDlg MyPrStlInit(hPrint)
  296. THPrint hPrint;
  297. {
  298. TPPrDlg tp;
  299. short type;
  300. Handle item;
  301. Rect box,listbox;
  302.  
  303.     tp = (TPPrDlg)NewPtr(DLGSIZE);
  304.     (GetNewDialog(STYLEDIALOG,tp,(WindowPtr)-1));
  305.     GetDItem(tp,STYLETITLE,&type,&item,&box);
  306.     listbox.left = box.right+20;
  307.     listbox.top = tp->Dlg.window.port.portRect.top+10;
  308.     listbox.bottom = tp->Dlg.window.port.portRect.bottom-10;
  309.     listbox.right = listbox.left + 200;
  310.     GetDItem(tp,STYLELIST,&type,&item,&box);
  311.     SetDItem(tp,STYLELIST,type,PRECuserItem,&listbox);
  312.     extra(tp,0) = nil;
  313.  
  314.     tp->pFltrProc = (ProcPtr)MyStlFilter;
  315.     tp->pItemProc = (ProcPtr)HandleStyleItems;
  316.     tp->hPrintUsr = hPrint;
  317.  
  318.     return(tp);
  319. }
  320. pascal Boolean  MyPrStlDialog(hPrint)   /* Conduct printer style dialog. */
  321. THPrint hPrint;
  322. {
  323.     return(MyPrDlgMain(hPrint,MyPrStlInit));
  324. }
  325. /*
  326.  * Record user choice of paper feed, page numbers, and
  327.  * number of copies.
  328.  */
  329. pascal void HandleJobItems(tp,itemhit)
  330. TPPrDlg tp;
  331. short       itemhit;
  332. {
  333. short       thenum;
  334. long        thelong;
  335. Handle      numitem;
  336. Rect        numbox;
  337. char        title[256];
  338.     switch(itemhit){
  339.         case DONEITEM:
  340.             tp->fDone = TRUE;
  341.             tp->fDoIt = TRUE;
  342.  
  343.             if(buttonset(tp,ALLBUTTON)){
  344.                 (*(tp->hPrintUsr))->prJob.iFstPage = iPrPgFst;
  345.                 (*(tp->hPrintUsr))->prJob.iLstPage = iPrPgMax;
  346.             }else{
  347.                 GetDItem(tp,FROMNUM,&thenum,&numitem,&numbox);
  348.                 GetIText(numitem,&title[0]);
  349.                 StringToNum(&title[0],&thelong);
  350.                 (*(tp->hPrintUsr))->prJob.iFstPage = thelong;
  351.                 GetDItem(tp,TONUM,&thenum,&numitem,&numbox);
  352.                 GetIText(numitem,&title[0]);
  353.                 StringToNum(&title[0],&thelong);
  354.                 (*(tp->hPrintUsr))->prJob.iLstPage = thelong;
  355.             }
  356.  
  357.             GetDItem(tp,COPIES,&thenum,&numitem,&numbox);
  358.             GetIText(numitem,&title[0]);
  359.             StringToNum(&title[0],&thelong);
  360.             (*(tp->hPrintUsr))->prJob.iCopies = (short)thelong;
  361.  
  362.             if(buttonset(tp,SHEETBUTTON)){
  363.                 (*(tp->hPrintUsr))->prStl.feed = feedCut;
  364.             }
  365.             else (*(tp->hPrintUsr))->prStl.feed = feedFanfold;
  366.             break;
  367.         case CANCELITEM:
  368.             tp->fDone = TRUE;
  369.             break;
  370.         case SHEETBUTTON:
  371.             pushradiobutton(tp,SHEETBUTTON,FANBUTTON,SHEETBUTTON);
  372.                 (*(tp->hPrintUsr))->prStl.feed = feedCut;
  373.             break;
  374.         case FANBUTTON:
  375.             pushradiobutton(tp,FANBUTTON,FANBUTTON,SHEETBUTTON);
  376.             (*(tp->hPrintUsr))->prStl.feed = feedFanfold;
  377.             break;
  378.         case ALLBUTTON:
  379.             pushradiobutton(tp,ALLBUTTON,ALLBUTTON,RANGEBUTTON);
  380.             break;
  381.         case RANGEBUTTON:
  382.             pushradiobutton(tp,RANGEBUTTON,ALLBUTTON,RANGEBUTTON);
  383.             break;
  384.         default:
  385.             break;
  386.     }
  387. }
  388. /*
  389.  * The job dialog initializer.  Make sure all the buttons
  390.  * come up reflecting the Print Record contents.
  391.  */
  392. pascal TPPrDlg  MyPrJobInit(hPrint)
  393. THPrint hPrint;
  394. {
  395. TPPrDlg     tp;
  396. short       thenum;
  397. Handle      theitem;
  398. Rect        thebox;
  399. char        title[255];
  400.     tp = (TPPrDlg)NewPtr(DLGSIZE);
  401.     (GetNewDialog(JOBDIALOG,tp,(WindowPtr)-1));
  402.     pushradiobutton(tp,ALLBUTTON,ALLBUTTON,RANGEBUTTON);
  403.     if( (*hPrint)->prStl.feed == feedCut)
  404.         pushradiobutton(tp,SHEETBUTTON,FANBUTTON,SHEETBUTTON);
  405.     else
  406.         pushradiobutton(tp,FANBUTTON,FANBUTTON,SHEETBUTTON);
  407.  
  408.     GetDItem(tp,FROMNUM,&thenum,&theitem,&thebox);
  409.     thenum = (*hPrint)->prJob.iFstPage;
  410.     NumToString((long)thenum,title);
  411.     SetIText(theitem,title);
  412.  
  413.     GetDItem(tp,TONUM,&thenum,&theitem,&thebox);
  414.     thenum = (*hPrint)->prJob.iLstPage;
  415.     NumToString((long)thenum,title);
  416.     SetIText(theitem,title);
  417.  
  418.     GetDItem(tp,COPIES,&thenum,&theitem,&thebox);
  419.     thenum = ((*hPrint)->prJob.iCopies /*= 1*/);
  420.     NumToString((long)thenum,title);
  421.     SetIText(theitem,title);
  422.  
  423.     tp->pFltrProc = (ProcPtr)MyFilter;
  424.     tp->pItemProc = (ProcPtr)HandleJobItems;
  425.     tp->hPrintUsr = hPrint;
  426.     return(tp);
  427. }
  428. pascal Boolean  MyPrJobDialog(hPrint)   /* Conduct printer job dialog. */
  429. THPrint hPrint;
  430. {
  431.     return(MyPrDlgMain(hPrint,MyPrJobInit));
  432. }
  433. /*
  434.  * Copy a job subrecord.  Update the destination record's printer information,
  435.  * band information, and paper rectangle, based on information in the job
  436.  * subrecord.
  437.  */
  438. pascal void MyPrJobMerge(hPrintSrc,hPrintDst)
  439. THPrint hPrintSrc,hPrintDst;
  440. {
  441.     (*hPrintDst)->prInfo.iDev = (*hPrintSrc)->prInfo.iDev;
  442.     (*hPrintDst)->prJob = (*hPrintSrc)->prJob;
  443.     (*hPrintDst)->prXInfo = (*hPrintSrc)->prXInfo;
  444.     (*hPrintDst)->rPaper = (*hPrintSrc)->rPaper;
  445.     (*hPrintDst)->prInfo = (*hPrintSrc)->prInfo;
  446.     (*hPrintDst)->prInfoPT = (*hPrintSrc)->prInfoPT;
  447. }
  448. /*
  449.  * Handy test for radio button down.
  450.  */
  451. int buttonset(d,num)
  452. DialogPtr   d;
  453. short       num;
  454. {
  455. short   type;
  456. Handle  item;
  457. Rect    box;
  458.     GetDItem(d,num,&type,&item,&box);
  459.     if(GetCtlValue(item) == 1){
  460.         return true;
  461.     }else{
  462.         return false;
  463.     }
  464. }
  465. pushradiobutton(thedialog,itemhit,first,last)   /* push a radio Button */
  466. DialogPtr thedialog;                /* set itemhit, unset  */
  467. int itemhit,first,last;             /* all others in range */
  468. {
  469.     int itemtype,i;
  470.     Handle itemhandle;          /* Does check boxes, too. */
  471.     Rect itemrect;
  472.     if(first ==0) return;
  473.     for(i=first-1;last-i++;){
  474.         GetDItem(thedialog,i,&itemtype,&itemhandle,&itemrect);
  475.         if(i == itemhit) SetCtlValue(itemhandle,1);
  476.         else SetCtlValue(itemhandle,0);
  477.     }
  478. }
  479. /*
  480.  * This function answers the question:  Can we possibly use this print
  481.  * record?  Try to be somewhat liberal here.  Don't allow a Print
  482.  * Record which will require a larger buffer than our printing
  483.  * routines can handle.
  484.  */
  485. int Valid(hPrint)
  486. THPrint hPrint;
  487. {
  488. if  (((*hPrint)->iPrVersion != VERSION)
  489.      || ((*hPrint)->prInfo.iDev != 0)
  490.  
  491.      || ((*hPrint)->prJob.bJDocLoop != bDraftLoop))
  492.  
  493.     return FALSE;
  494.  
  495. if(
  496.     (*hPrint)->prXInfo.iBandV != 64 ||
  497.     (*hPrint)->prXInfo.iBandH != 959 ||
  498.     (*hPrint)->prXInfo.iRowBytes != 120
  499.     )
  500.     return FALSE;
  501.  
  502.     return  TRUE;
  503. }
  504.